package com.aiwu.memory;

import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SimpleItemAnimator;

import com.aiwu.BaseLazyFragment;
import com.aiwu.Util;
import com.aiwu.bean.MemoryBean;
import com.aiwu.library.App;
import com.aiwu.library.util.DisplayUtil;
import com.aiwu.library.util.ToastUtil;

import org.citra.citra_emu.NativeLibrary;
import org.citra.citra_emu.R;
import org.citra.citra_emu.ui.DividerItemDecoration;

import java.util.ArrayList;
import java.util.List;

/**
 * 搜索结果列表
 */
public class MemoryResultListFragment extends BaseLazyFragment implements View.OnClickListener, OnActionCallback {
    private static final String TAG = MemoryResultListFragment.class.getName();
    private ViewGroup layoutBottom;
    private TextView tvTip, tvModify, tvCreateCheat, tvContinueSearch;
    private EditText etNum;
    private CheckBox cbSelectAll;
    private RecyclerView rv;
    private MemoryAdapter memoryAdapter = new MemoryAdapter();

    @Override
    protected void lazyLoad() {
        List<MemoryBean> memoryList = MemoryManager.getInstance().getMemoryList();
        int resultSize = memoryList.size();
        if (resultSize > 0 && resultSize <= MemoryManager.RESULT_NUM_THRESHOLD) {
            notifyTip(resultSize);
            for (MemoryBean item : memoryList) {
                long address = item.getAddress();
                long value = MemoryManager.GetUnsigned(NativeLibrary.readMemory(MemoryManager.GetSigned(address), 0));
                item.setValue(value);
            }
            notifyData(memoryList);
        }
    }

    @Override
    protected Boolean repeatedLoad() {
        return true;
    }

    @Override
    protected int initContentView() {
        return R.layout.fragment_memory_result_list;
    }

    @Override
    protected void initView(View view) {
        layoutBottom = view.findViewById(R.id.layout_bottom);
        tvTip = view.findViewById(R.id.tv_tip);
        tvModify = view.findViewById(R.id.tv_modify);
        tvModify.setOnClickListener(this);
        tvCreateCheat = view.findViewById(R.id.tv_create_cheat);
        tvCreateCheat.setOnClickListener(this);
        tvContinueSearch = view.findViewById(R.id.tv_continue_search);
        tvContinueSearch.setOnClickListener(this);
        etNum = view.findViewById(R.id.et_num);
        cbSelectAll = view.findViewById(R.id.cb_select_all);
        cbSelectAll.setOnCheckedChangeListener((buttonView, isChecked) -> {
            if (buttonView.isPressed()) {
                selectAll(isChecked);
            }
        });
        rv = view.findViewById(R.id.rv);
        if (getContext() != null) {
            rv.addItemDecoration(new DividerItemDecoration(getContext(), null));
            rv.setLayoutManager(new LinearLayoutManager(getContext()));
        }
        SimpleItemAnimator animator = ((SimpleItemAnimator) rv.getItemAnimator());
        if (animator != null) {
            animator.setSupportsChangeAnimations(false);
        }
        rv.setAdapter(memoryAdapter);
        memoryAdapter.setOnItemChildClickListener((adapter, view1, position) -> {
            if (view1.getId() == R.id.iv_delete) {
                memoryAdapter.remove(position);
                resetIfNecessary();
                notifyTip(memoryAdapter.getItemCount());
                notifyCbSelectAll();
            } else if (view1.getId() == R.id.iv_lock) {
                MemoryBean memoryBean = memoryAdapter.getData().get(position);
                if (memoryBean != null) {
                    boolean newState = !memoryBean.isLocking();
                    memoryBean.setLocking(newState);
                    if (newState) {
                        MemoryManager.getInstance().addLockMemory(memoryBean);
                    } else {
                        MemoryManager.getInstance().removeLockMemory(memoryBean);
                    }
                }
                memoryAdapter.notifyItemChanged(position);
            }
        });

        MemoryManager.disableShowInput(etNum, false);
        MemoryManager.getInstance().addOnActionCallback(this);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        MemoryManager.getInstance().removeOnActionCallback(this);
    }

    /**
     * 必要的话重置步骤
     */
    private void resetIfNecessary() {
        if (MemoryManager.getInstance().getMemoryList().isEmpty()) {
            MemoryManager.getInstance().reset();
        }
    }

    private void notifyData(List<MemoryBean> memoryList) {
        memoryAdapter.setData(memoryList);
        rv.post(() -> {
            int maxHeight = (int) (DisplayUtil.getAppScreenHeight() * (DisplayUtil.isPortrait() ? 0.5f : 0.3f));
            if (rv.getMeasuredHeight() > maxHeight) {
                ViewGroup.LayoutParams lp = rv.getLayoutParams();
                lp.height = maxHeight;
                rv.setLayoutParams(lp);
            }
        });
        notifyCbSelectAll();
    }

    /**
     * 刷新提示文本
     *
     * @param size
     */
    private void notifyTip(int size) {
        String tipStr = "共搜索到" + size + "个数值，把他们修改为?";
        SpannableString ssTip = new SpannableString(tipStr);
        int start2 = 4;
        int end2 = tipStr.indexOf("个数值");
        ssTip.setSpan(new ForegroundColorSpan(ContextCompat.getColor(App.getContext(), R.color.text_imp)), start2, end2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        tvTip.setText(ssTip);
    }

    /**
     * 刷新全选按钮
     */
    private void notifyCbSelectAll() {
        boolean isSelectAll = true;
        for (MemoryBean item : memoryAdapter.getData()) {
            if (!item.isSelected()) {
                isSelectAll = false;
                break;
            }
        }
        cbSelectAll.setChecked(isSelectAll);
    }

    /**
     * 全选/全不选
     *
     * @param select
     */
    private void selectAll(boolean select) {
        for (MemoryBean item : memoryAdapter.getData()) {
            item.setSelected(select);
        }
        memoryAdapter.notifyDataSetChanged();
    }

    private void modifyMemory() {
        String strValue = etNum.getText().toString();
        if (TextUtils.isEmpty(strValue)) {
            ToastUtil.toast("请输入修改的值");
            return;
        }
        if (MemoryManager.isValueValid(strValue)) {
            MemoryManager.getInstance().modifyMemory(strValue);
        } else {
            ToastUtil.toast("输入的值有误，请重新输入");
            etNum.setText("");
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.tv_continue_search:
                MemoryManager.getInstance().backGame();
                break;
            case R.id.tv_modify:
                modifyMemory();
                break;
            case R.id.tv_create_cheat:
                MemoryManager.getInstance().createCheat();
                break;
        }
    }

    @Override
    public void onShowKeyboard() {
        if (getContext() != null) {
            if (DisplayUtil.isLandscape()) {
                layoutBottom.setBackgroundResource(R.drawable.dialog_bottom_left);
            }
        }
    }

    @Override
    public void onCloseKeyboard() {
        if (getContext() != null) {
            if (DisplayUtil.isLandscape()) {
                layoutBottom.setBackgroundResource(R.drawable.dialog_bottom);
            }
        }
    }

    public interface OnItemChildClickListener {
        void onItemChildClick(MemoryAdapter adapter, View view, int position);
    }

    public class MemoryAdapter extends RecyclerView.Adapter<MemoryHolder> {

        private List<MemoryBean> mData;
        private OnItemChildClickListener mOnItemChildClickListener;

        @NonNull
        @Override
        public MemoryHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
            View view = inflater.inflate(R.layout.item_memory, parent, false);
            return new MemoryHolder(view, this);
        }

        @Override
        public void onBindViewHolder(@NonNull MemoryHolder holder, int position) {
            holder.bind(mData.get(position));
        }

        @Override
        public int getItemCount() {
            return mData != null ? mData.size() : 0;
        }

        public void setData(List<MemoryBean> mData) {
            this.mData = mData;
            notifyDataSetChanged();
        }

        public List<MemoryBean> getData() {
            return mData == null ? new ArrayList<>() : mData;
        }

        public void remove(@IntRange(from = 0L) int position) {
            this.mData.remove(position);
            notifyDataSetChanged();
        }

        public void setOnItemChildClickListener(OnItemChildClickListener listener) {
            this.mOnItemChildClickListener = listener;
        }

        public OnItemChildClickListener getOnItemChildClickListener() {
            return mOnItemChildClickListener;
        }
    }

    public class MemoryHolder extends RecyclerView.ViewHolder {
        private CheckBox cbSelected;
        private TextView tvMemory;
        private ImageView ivLocked;
        private ImageView ivDelete;
        private MemoryAdapter adapter;

        public MemoryHolder(View itemView, @NonNull MemoryAdapter adapter) {
            super(itemView);
            this.adapter = adapter;
            cbSelected = itemView.findViewById(R.id.cb_selected);
            tvMemory = itemView.findViewById(R.id.tv_memory);
            ivLocked = itemView.findViewById(R.id.iv_lock);
            ivDelete = itemView.findViewById(R.id.iv_delete);
            cbSelected.setOnCheckedChangeListener((buttonView, isChecked) -> {
                if (buttonView.isPressed()) {
                    int position = getAdapterPosition();
                    if (position == -1) {
                        return;
                    }
                    MemoryBean memoryBean = adapter.getData().get(position);
                    memoryBean.setSelected(isChecked);
                    notifyCbSelectAll();
                }
            });
            ivLocked.setOnClickListener(this::onItemChildClick);
            ivDelete.setOnClickListener(this::onItemChildClick);
        }

        private void onItemChildClick(View v) {
            if (adapter.getOnItemChildClickListener() != null) {
                int position = getAdapterPosition();
                if (position == -1) {
                    return;
                }
                adapter.getOnItemChildClickListener().onItemChildClick(adapter, v, position);
            }
        }

        public void bind(MemoryBean memoryBean) {
            cbSelected.setChecked(memoryBean.isSelected());
            tvMemory.setText(memoryBean.getAddressStr() + ":" + memoryBean.getValueStr());
            ivLocked.setImageResource(memoryBean.isLocking() ? R.drawable.ic_memory_locked : R.drawable.ic_memory_unlock);
        }
    }
}
